<!--
  Uploader 文件上传组件                 zls-2022/06/04
    所有属性、事件、方法、插槽，请参考  https://vant-contrib.gitee.io/vant/#/zh-CN/uploader
-->
<template>
  <Field
    class="z-input"
    :name="$attrs['name']"
    :label="$attrs['label']"
    :required="$attrs['required']"
    :rules="$attrs['required'] || $attrs['required'] === '' ? [{ required: true, message: '请选择' }] : []"
    :placeholder="$attrs['placeholder'] || '请选择'"
    :border="$attrs['border']"
    :colon="$attrs['colon']"
    :label-width="$attrs['label-width']"
    @click="show = true"
  >
    <template #input>
      <Uploader
        v-model="fileList.list"
        :accept="$attrs['accept'] || '*'"
        :name="$attrs['name']"
        :preview-size="$attrs['preview-size'] || pxToRem(78)"
        :preview-image="$attrs['preview-image']"
        :preview-full-image="$attrs['preview-full-image']"
        :preview-options="$attrs['preview-options']"
        :multiple="$attrs['multiple']"
        :disabled="$attrs['disabled']"
        :readonly="$attrs['readonly']"
        :deletable="$attrs['deletable']"
        :show-upload="$attrs['show-upload']"
        :capture="$attrs['capture']"
        :max-size="$attrs['max-size']"
        :max-count="$attrs['max-count']"
        :result-type="$attrs['result-type']"
        :upload-text="$attrs['upload-text']"
        :image-fit="$attrs['image-fit']"
        :upload-icon="$attrs['upload-icon']"
        :before-read="$attrs['before-read']"
        :after-read="$attrs['after-read']"
        :before-delete="deleteFile"
        @click-preview="clickPreview"
      >
        <template #preview-cover="{ name, type }">
          <img v-if="type !== 'image'" class="preview-cover" :src="fileTypeObj[type]" alt="" />
          <div v-if="name" class="preview-tip">{{ name }}</div>
        </template>
      </Uploader>
    </template>
  </Field>
</template>

<script>
export default { name: 'z-uploader' }
</script>
<script setup>
import { watch, reactive } from 'vue'
import { Field, Uploader, Dialog, Notify } from 'vant'
import { pxToRem } from '@/utils'
import word from '@img/uploader/word.png'
import excel from '@img/uploader/excel.png'
import ppt from '@img/uploader/ppt.png'
import txt from '@img/uploader/txt.png'
import pdf from '@img/uploader/pdf.png'
import zip from '@img/uploader/zip.png'
import audio from '@img/uploader/audio.png'
import video from '@img/uploader/video.png'
// 根据文件类型，设置对应的图片
const fileTypeObj = { word, excel, ppt, txt, pdf, zip, audio, video }
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => null
  }
})

const fileList = reactive({ list: [] }) // 文件列表，格式：[{url:'',type:'',name:''}]

watch(
  () => props.modelValue,
  newVal => {
    fileList.list = newVal ?? []
  },
  { immediate: true, deep: true }
)

// 删除文件时触发（调用后台文件服务删除该文件）
function deleteFile(file, detail) {
  Dialog.confirm({ message: '确定删除该文件吗?' })
    .then(() => {
      setTimeout(() => {
        fileList.list.splice(detail.index, 1)
        emit('update:modelValue', fileList.list)
        Notify({ type: 'success', message: '删除成功' })
      }, 1000)
    })
    .catch(() => {})
}

// 点击文件直接打开（除image图片外）
function clickPreview(file) {
  console.log('--打开文件--', file)
  if (file.type === 'image') return
  window.open(file.url)
}
</script>

<style lang="scss" scoped>
.van-field {
  display: flex;
  flex-direction: column;
  .van-cell__title {
    margin-bottom: 5px;
  }
  .preview-cover {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .preview-tip {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 24px;
    line-height: 24px;
    padding: 0 2px;
    color: #fff;
    font-size: 12px;
    text-align: center;
    background: rgba(0, 0, 0, 0.4);
    @include oflow();
  }
}
</style>
